#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
cx_Freeze打包脚本 - 拾取窗中流光 v2.0
优化的打包配置，支持ttkbootstrap和Socket.IO
作者：adnaan
"""

import os
import sys
import shutil
from pathlib import Path

def create_setup_script(main_py_path="../src/main.py"):
    """创建cx_Freeze的setup.py文件 - 现代化版本"""
    setup_content = '''
import sys
import os

# 修复Python 3.12+中distutils模块缺失问题
try:
    import distutils
except ImportError:
    try:
        import setuptools
        sys.modules['distutils'] = setuptools
        import setuptools.version
        sys.modules['distutils.version'] = setuptools.version
        import setuptools.dist
        sys.modules['distutils.dist'] = setuptools.dist
        import setuptools.command
        sys.modules['distutils.command'] = setuptools.command
        import setuptools.command.build_ext
        sys.modules['distutils.command.build_ext'] = setuptools.command.build_ext
        import setuptools.command.build_py
        sys.modules['distutils.command.build_py'] = setuptools.command.build_py
        import setuptools.command.build_scripts
        sys.modules['distutils.command.build_scripts'] = setuptools.command.build_scripts
        import setuptools.command.install
        sys.modules['distutils.command.install'] = setuptools.command.install
        import setuptools.command.install_lib
        sys.modules['distutils.command.install_lib'] = setuptools.command.install_lib
        import setuptools.command.install_scripts
        sys.modules['distutils.command.install_scripts'] = setuptools.command.install_scripts
        import setuptools.command.sdist
        sys.modules['distutils.command.sdist'] = setuptools.command.sdist
        import setuptools.extension
        sys.modules['distutils.extension'] = setuptools.extension
        import setuptools.util
        sys.modules['distutils.util'] = setuptools.util
        import setuptools.errors
        sys.modules['distutils.errors'] = setuptools.errors
        import setuptools.log
        sys.modules['distutils.log'] = setuptools.log
        import setuptools.spawn
        sys.modules['distutils.spawn'] = setuptools.spawn
        import setuptools.file_util
        sys.modules['distutils.file_util'] = setuptools.file_util
        import setuptools.dir_util
        sys.modules['distutils.dir_util'] = setuptools.dir_util
        import setuptools.dep_util
        sys.modules['distutils.dep_util'] = setuptools.dep_util
        import setuptools.archive_util
        sys.modules['distutils.archive_util'] = setuptools.archive_util
        import setuptools.core
        sys.modules['distutils.core'] = setuptools.core
        import setuptools
        sys.modules['distutils'] = setuptools
    except ImportError:
        pass

from cx_Freeze import setup, Executable

# 现代化依赖包配置
packages = [
    # 现代化GUI库
    "ttkbootstrap", "tkinter", "tkinter.ttk", "tkinter.messagebox", 
    "tkinter.colorchooser", "tkinter.simpledialog", "tkinter.filedialog",
    "tkinter.scrolledtext",
    
    # 系统托盘和图像处理
    "pystray", "PIL", "PIL.Image", "PIL.ImageDraw", "PIL.ImageTk",
    
    # 核心功能模块
    "psutil", "requests", "configparser", "json", "pathlib",
    
    # Windows API
    "win32gui", "win32process", "win32api", "win32con",
    
    # Socket.IO客户端及依赖
    "socketio", "engineio", "websocket", "simple_websocket",
    "bidict", "wsproto", "h11",
    
    # 网络和HTTP
    "urllib", "urllib.parse", "urllib3", "http", "http.client",
    "ssl", "socket", "socketserver", "certifi",
    
    # 日志和线程
    "logging", "threading", "queue", "time", "datetime",
    
    # 数据处理
    "base64", "hashlib", "uuid", "collections", "itertools",
    "functools", "inspect", "importlib", "importlib.metadata",
    
    # 兼容性模块 (处理distutils问题)
    "distutils", "distutils.version", "setuptools",
    
    # 标准库核心
    "sys", "os", "subprocess", "shutil", "tempfile", "re",
    "warnings", "weakref", "copy", "io", "struct", "typing",
]

# 排除不需要的包（减小体积）
excludes = [
    # 测试和开发工具
    "test", "unittest", "email", "xml", "pydoc", "doctest", 
    "difflib", "pip",
    
    # 不需要的GUI库
    "matplotlib", "numpy", "pandas", "scipy",
    
    # 其他大型库
    "jupyter", "notebook", "IPython"
]

# 包含的文件和数据
include_files = []

# 检查并包含配置文件
if os.path.exists("../config.ini"):
    include_files.append(("../config.ini", "config.ini"))

# 检查并包含图标文件
icon_files = ["../icon.ico", "../src/icon.ico"]
for icon_file in icon_files:
    if os.path.exists(icon_file):
        include_files.append((icon_file, "icon.ico"))
        break

# 包含CustomTkinter主题文件
try:
    import customtkinter
    ctk_path = os.path.dirname(customtkinter.__file__)
    assets_path = os.path.join(ctk_path, "assets")
    if os.path.exists(assets_path):
        include_files.append((assets_path, "customtkinter/assets"))
except ImportError:
    pass

# 构建选项 - 优化配置
build_options = {
    "packages": packages,
    "excludes": excludes,
    "include_files": include_files,
    "optimize": 2,  # 最高优化级别
    "build_exe": "dist",  # 输出目录
}

# 可执行文件配置
base = None
if sys.platform == "win32":
    base = "Win32GUI"  # Windows GUI应用，无控制台

# 查找图标文件
icon_path = None
for icon_file in ["../icon.ico", "../src/icon.ico", "icon.ico"]:
    if os.path.exists(icon_file):
        icon_path = icon_file
        break

executables = [
    Executable(
        script="MAIN_PY_PATH_PLACEHOLDER",
        base=base,
        target_name="LightCapture.exe",
        icon=icon_path,
        copyright="拾取窗中流光 v2.0 - 作者: adnaan",
        shortcut_name="拾取窗中流光",
        shortcut_dir="DesktopFolder"
    )
]

setup(
    name="LightCapture",
    version="2.0.0",
    description="拾取窗中流光 - Socket.IO实时推送",
    author="adnaan",
    options={"build_exe": build_options},
    executables=executables
)
'''
    
    with open('temp_setup.py', 'w', encoding='utf-8') as f:
        content = setup_content.replace("MAIN_PY_PATH_PLACEHOLDER", main_py_path)
        f.write(content)
    print("✅ 已创建现代化cx_Freeze配置文件")

def install_dependencies():
    """安装现代化版本的依赖包"""
    print("📦 检查现代化UI依赖包...")
    
    required_packages = [
        # 打包工具
        'cx_Freeze',
        
        # 兼容性工具 (解决distutils问题)
        'setuptools',
        
        # 现代化UI
        'customtkinter>=5.2.0',
        
        # 核心功能
        'pystray>=0.19.4',
        'pillow>=9.0.0',
        'psutil>=5.9.0',
        'requests>=2.28.0',
        'pywin32>=305',
        
        # Socket.IO
        'python-socketio[client]>=5.8.0',
    ]
    
    import subprocess
    
    failed_packages = []
    
    for package in required_packages:
        package_name = package.split('>=')[0].split('==')[0]
        try:
            # 特殊处理某些包名
            import_name = package_name
            if package_name == 'python-socketio':
                import_name = 'socketio'
            elif package_name == 'pillow':
                import_name = 'PIL'
            elif package_name == 'pywin32':
                import_name = 'win32gui'
            
            __import__(import_name)
            print(f"✅ {package_name} 已安装")
        except ImportError:
            print(f"📥 正在安装 {package}...")
            try:
                subprocess.check_call([
                    sys.executable, "-m", "pip", "install", 
                    package, "--upgrade"
                ], timeout=300)
                print(f"✅ {package} 安装成功")
            except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
                print(f"❌ {package} 安装失败: {e}")
                failed_packages.append(package)
    
    if failed_packages:
        print(f"\n⚠️ 以下包安装失败: {', '.join(failed_packages)}")
        print("💡 请手动安装这些包后重试")
        return False
    
    return True

def build_with_cx_freeze():
    """使用cx_Freeze打包现代化版本"""
    print("🚀 开始打包现代化状态监控工具...")
    
    # 检查源文件 - 支持从不同目录运行
    main_py_paths = ["../src/main.py", "src/main.py", "./src/main.py"]
    main_py_path = None
    
    for path in main_py_paths:
        if os.path.exists(path):
            main_py_path = path
            break
    
    if not main_py_path:
        print("❌ 找不到主程序文件，尝试过的路径:")
        for path in main_py_paths:
            print(f"  - {path}")
        return False
    
    print(f"✅ 找到主程序文件: {main_py_path}")
    
    # 安装依赖
    print("\n📋 步骤 1/4: 检查依赖...")
    if not install_dependencies():
        print("❌ 依赖检查失败，无法继续打包")
        return False
    
    # 创建setup脚本
    print("\n📋 步骤 2/4: 创建打包配置...")
    create_setup_script(main_py_path)
    
    # 清理旧文件
    print("\n📋 步骤 3/4: 清理旧文件...")
    for old_dir in ['build', 'dist']:
        if os.path.exists(old_dir):
            try:
                shutil.rmtree(old_dir)
                print(f"🗑️ 已清理 {old_dir} 目录")
            except PermissionError as e:
                print(f"⚠️ 无法清理 {old_dir}: {e}")
                print("💡 请关闭可能运行的程序后重试")
                # 继续执行，不阻断打包
            except Exception as e:
                print(f"⚠️ 清理失败: {e}")
    
    # 执行打包
    print("\n📋 步骤 4/4: 开始打包...")
    import subprocess
    try:
        print("⚙️ 正在使用cx_Freeze打包，这可能需要几分钟...")
        
        # 显示打包进度
        process = subprocess.Popen([
            sys.executable, "temp_setup.py", "build_exe"
        ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 
        text=True, universal_newlines=True)
        
        # 实时显示输出
        for line in process.stdout:
            line = line.strip()
            if line:
                if "copying" in line.lower():
                    print(f"📁 {line}")
                elif "error" in line.lower():
                    print(f"❌ {line}")
                elif "warning" in line.lower():
                    print(f"⚠️ {line}")
        
        process.wait()
        
        if process.returncode == 0:
            print("\n✅ cx_Freeze打包成功!")
            
            # 检查生成的文件
            dist_path = Path("dist")
            if dist_path.exists():
                exe_files = list(dist_path.glob("*.exe"))
                if exe_files:
                    print(f"\n📋 生成的文件:")
                    total_size = 0
                    for exe_file in exe_files:
                        size_mb = exe_file.stat().st_size / (1024 * 1024)
                        total_size += size_mb
                        print(f"  📄 {exe_file.name} ({size_mb:.1f} MB)")
                    
                    print(f"\n📊 打包统计:")
                    print(f"  📁 输出目录: {dist_path.absolute()}")
                    print(f"  📦 总大小: {total_size:.1f} MB")
                    print(f"  🗂️ 文件数量: {len(list(dist_path.iterdir()))}")
                    
                    print(f"\n🎉 打包完成! 使用说明:")
                    print(f"  1. 📂 进入 dist 目录")
                    print(f"  2. 🚀 双击 LightCapture.exe 启动")
                    print(f"  3. 📊 程序将在系统托盘运行")
                    print(f"  4. 🖱️ 右键托盘图标打开现代化控制面板")
                    print(f"  5. ⚙️ 配置Webhook URL后开始监控")
                    
                    return True
                else:
                    print("❌ 未找到生成的exe文件")
                    return False
            else:
                print("❌ 未找到输出目录")
                return False
        else:
            print(f"❌ 打包失败，返回码: {process.returncode}")
            return False
            
    except Exception as e:
        print(f"❌ 打包过程出错: {e}")
        return False
    finally:
        # 清理临时文件
        if os.path.exists('temp_setup.py'):
            os.remove('temp_setup.py')
            print("🗑️ 已清理临时配置文件")

def create_portable_package():
    """创建便携版包"""
    print("\n📦 创建便携版...")
    
    dist_path = Path("dist")
    if not dist_path.exists():
        print("❌ 找不到dist目录，请先完成打包")
        return False
    
    # 创建便携版目录
    portable_path = Path("LightCapture_Portable")
    if portable_path.exists():
        shutil.rmtree(portable_path)
    
    # 复制文件
    shutil.copytree(dist_path, portable_path)
    
    # 创建启动脚本
    start_script = portable_path / "启动监控工具.bat"
    with open(start_script, 'w', encoding='utf-8') as f:
        f.write('''@echo off
title 状态监控工具 v2.0
echo 🚀 正在启动状态监控工具...
echo 📊 程序将在系统托盘运行
echo 🖱️ 右键托盘图标打开控制面板
echo.
LightCapture.exe
''')
    
    # 创建说明文件
    readme_file = portable_path / "使用说明.txt"
    with open(readme_file, 'w', encoding='utf-8') as f:
        f.write('''✨ 拾取窗中流光 v2.0 - 便携版

🚀 快速开始:
1. 双击 "启动监控工具.bat" 或 "LightCapture.exe"
2. 程序在系统托盘运行（右下角）
3. 右键托盘图标，选择"打开控制面板"
4. 配置Webhook URL，开始监控

✨ 主要功能:
• 实时监控Windows应用程序切换
• 智能识别音乐播放器并显示歌曲信息  
• Socket.IO实时推送，低延迟高可靠
• 现代化深色主题界面
• 完整的实时日志系统
• 智能防抖动避免频繁推送

🔧 系统要求:
• Windows 7/8/10/11
• 网络连接（用于推送状态）

💡 技术支持:
• 遇到问题请查看"实时日志"标签页
• 确保目标服务器支持Socket.IO 4.x+
• 建议使用提供的后端服务配套使用
''')
    
    print(f"✅ 便携版创建完成: {portable_path}")
    return True

def main():
    """主函数"""
    print("🚀 拾取窗中流光 v2.0 - 现代化打包器")
    print("✨ 作者: adnaan")
    print("=" * 60)
    print("📊 现代化UI + Socket.IO + 实时日志")
    print("⚡ 使用cx_Freeze快速打包")
    print("🎨 支持CustomTkinter现代界面")
    print()
    
    # 检查Python版本
    if sys.version_info < (3, 8):
        print("❌ 需要Python 3.8或更高版本")
        print(f"当前版本: {sys.version}")
        return
    
    print(f"✅ Python版本: {sys.version.split()[0]}")
    
    # 检查源文件
    main_py_paths = ["../src/main.py", "src/main.py", "./src/main.py"]
    main_py_found = any(os.path.exists(path) for path in main_py_paths)
    
    if not main_py_found:
        print("❌ 缺少必要的源文件:")
        for path in main_py_paths:
            print(f"  - {path}")
        return
    
    print("✅ 源文件检查通过")
    
    # 开始打包流程
    print("\n" + "="*60)
    print("🚀 开始打包流程")
    print("="*60)
    
    success = build_with_cx_freeze()
    
    if success:
        print("\n" + "="*60)
        print("🎉 打包成功完成!")
        print("="*60)
        
        # 询问是否创建便携版
        try:
            choice = input("\n是否创建便携版包? (y/n): ").lower()
            if choice in ['y', 'yes', '是']:
                create_portable_package()
        except KeyboardInterrupt:
            print("\n👋 用户取消")
        
        print(f"\n💡 使用提示:")
        print(f"  🎯 直接运行: dist/LightCapture.exe")
        print(f"  📦 便携版: LightCapture_Portable/")
        print(f"  🎨 现代化界面: 右键托盘 → 打开控制面板")
        print(f"  📊 实时日志: 控制面板 → 实时日志标签")
    else:
        print("\n❌ 打包失败")
        print("💡 请检查上述错误信息并重试")

if __name__ == "__main__":
    main() 